﻿// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "miHoYo/Character/Simple_Emission" {

	Properties
	{
		_Color ("Main Color", Color) = (0.5,0.5,0.5,1)
		_EmissionColor ("Emmisive Color", Color) = (0.5,0.5,0.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline ("Outline Width", Float) = 0.02
		_SpecMulti ("Specular Multiply", float) = 1.0
		_Shininess ("Shininess", float) = 2.0
		_FadeDistance ("Fade Start Distance", Range(0.1, 10)) = 0.5
		_FadeOffset ("Fade Start Offset", Range(0, 10)) = 1.0
		_BloomFactor ("Bloom Factor", float) = 1
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Ramp ("Toon Ramp (RGB)", 2D) = "white" {}
		_SpecRamp ("Specular Ramp (RGB)", 2D) = "black" {} 

		//Emission
		_Emission ("Emission", Range(1, 100)) = 1
		_EmissionBloomFactor ("Emission Bloom Factor", Float) = 1
	}

	SubShader
	{
		Tags
		{
			"Queue"="Transparent"
			"IgnoreProjector"="True"
			"RenderType"="Transparent"
		}

		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

			Name "BASE"
			Cull Back
			Blend SrcAlpha OneMinusSrcAlpha
			ZWrite On
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "../Common/Common_Util.cginc" 

			float4 _Color;
			sampler2D _MainTex;
			half4 _MainTex_ST;
			sampler2D _Ramp;
			float _FadeDistance;
			float _FadeOffset;
			sampler2D _SpecRamp;
			float _SpecMulti;
			float _Shininess;
			half _BloomFactor;
			
			half _Emission;

			struct appdata
			{
				float4 position : POSITION0;
				float3 normal : NORMAL;
				half2 uv_MainTex : TEXCOORD0;
			};
			
			struct v2f
			{
				float4 position : POSITION0;
				float4 color : COLOR0;
				half2 uv_MainTex : TEXCOORD0;
				half2 dd : TEXCOORD1;
				half2 ss : TEXCOORD2;
			};

			v2f vert (appdata in_data)
			{
				v2f outData = (v2f)0;

				outData.position = UnityObjectToClipPos (in_data.position);
				
				//Texture
				outData.uv_MainTex = TRANSFORM_TEX(in_data.uv_MainTex, _MainTex);

				//Lighting Toon Ramp
				float3 L = normalize(_WorldSpaceLightPos0);
				float3 N = mul((float3x3)unity_ObjectToWorld, in_data.normal.xyz);
				N = normalize(N);

				half d = dot(N, L) * 0.4975f + 0.5f;
				outData.dd = half2(d, d);

				//Specular
				float4 verPos = mul(unity_ObjectToWorld, in_data.position);
				float3 V = _WorldSpaceCameraPos - verPos.xyz;
				V = normalize(V);
				float3 H = normalize(L + V);
				half s = pow(max(dot(N, H), 0), _Shininess);
				if(d <= 0.5)
				{
					s = 0.025;
				}
				outData.ss = float2(s, s);

				//Handle Near Camera Fade
				half alpha = camera_fade(in_data.position, _FadeOffset, _FadeDistance);
				
				outData.color.a = alpha;

				return outData;
			}

			float4 frag (v2f in_data) : COLOR
			{
				float4 outColor = (float4)0;
				
				float4 tex_C_Color = (tex2D(_MainTex, in_data.uv_MainTex) * _Color);
				float3 ramp = (tex2D(_Ramp, in_data.dd)).rgb;
	
				float3 specRamp = tex2D (_SpecRamp, in_data.ss).rgb * _SpecMulti + 1.0f;

				//outColor.rgb = tex_C_Color * ramp;
				//outColor.rgb = tex_C_Color * specRamp;
				outColor.rgb = tex_C_Color.rgb * specRamp * ramp;

				// emission
				outColor.rgb *= lerp(1, _Emission, tex_C_Color.a);
	
				outColor.a = in_data.color.a;
				return outColor;
			}
			ENDCG			
		}

		Pass
		{
			Name "OUTLINE"
			Cull Front
			Blend SrcAlpha OneMinusSrcAlpha
			ZWrite On
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "../Common/Common_Util.cginc" 

			float4 _OutlineColor;
			float _Outline;
			float _FadeDistance;
			float _FadeOffset;

			struct appdata
			{
				float4 position : POSITION0;
				float3 normal : NORMAL;
			};
			
			struct v2f
			{
				float4 position : POSITION0;
				float4 color : COLOR0;
			};

			v2f vert (appdata in_data)
			{
				v2f outData = (v2f)0;

				outData.position = UnityObjectToClipPos (in_data.position);
				
				float3 N = mul ((float3x3)UNITY_MATRIX_IT_MV, in_data.normal);
				N = normalize(N);
				float2 offset = TransformViewToProjection(N.xy);

				outData.position.xy += offset * _Outline;
				outData.color = _OutlineColor;

				//Handle Near Camera Fade
				half alpha = camera_fade(in_data.position, _FadeOffset, _FadeDistance);
				
				outData.color.a *= alpha;

				return outData;
			}

			float4 frag (v2f in_data) : COLOR
			{
				float4 outColor = (float4)0;
	
				outColor = in_data.color;
	
				return outColor;
			}
			ENDCG			
		}

		//Bloom Pass
		Pass
		{
			Name "CONSTANT_REPLACE"
			ColorMask A

			CGPROGRAM
			#include "../Common/Common_Bloom.cginc"
			#pragma vertex vert_uv
			#pragma fragment frag_emission

			half _EmissionBloomFactor;

			half4 frag_emission(v2f_uv i) : SV_Target
			{
				half4 o = (half4)0;
				
				half4 tex_color = tex2D(_MainTex, i.texcoord);
				o.a = lerp(_BloomFactor, _EmissionBloomFactor, tex_color.a);

				return o;
			}

			ENDCG
		} // End of Bloom Pass
	}
	
	FallBack "Diffuse"
}
